# 一 前言
本章节,我们会从 0 到 1 实现一个 React 路由功能,这里可以称之为 mini-Router。实现的过程中会包含如下知识点:
- 路由更新流程与原理;
- 自定义 hooks 编写与使用;
- context 实践;
- hoc 编写与使用。
# 二 设计思路
整个 mini-Router 还是采用 history 库,也就是 mini-Router 需要完成的是 React-Router 和 React-Router-DOM 核心部分。今天编写的 mini-Router 是在 BrowserHistory 模式下。
# 1 建立目标
接下来要实现的具体功能如下:
- 组件层面: 在组件层面,需要实现提供路由状态的 Router ,控制渲染的 Route ,匹配唯一路由的 Switch 。
- api层面: 提供获取 history 对象的 useHistory 方法,获取 location 对象的 useLocation 方法。
- 高阶组件层面: 对于不是路由的页面,提供 withRouter,能够获取当前路由状态。
- 额外功能: 之前有很多同学问过我,在 React 应用中,可不可以提供有方法监听路由改变,所以 mini-Router 需要做的是增加路由监听器,当路由改变,触发路由监听器。
# 2 设计功能图

# 三 代码实现
# 1 组件层面
提供路由更新派发——Router
import React ,{ useCallback, useState , useEffect ,createContext, useMemo } from 'react'
import { createBrowserHistory as createHistory } from 'history'
export const RouterContext = createContext()
export let rootHistory = null
export default function Router(props){
/* 缓存history属性 */
const history = useMemo(() => {
rootHistory = createHistory()
return rootHistory
},[])
const [ location, setLocation ] = useState(history.location)
useEffect(()=>{
/* 监听location变化,通知更新 */
const unlisten = history.listen((location)=>{
setLocation(location)
})
return function () {
unlisten && unlisten()
}
},[])
return <RouterContext.Provider
value={{
location,
history,
match: { path: '/', url: '/', params: {}, isExact: location.pathname === '/' }
}}
>
{props.children}
</RouterContext.Provider>
}
